﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CustomAuthorizationDemo.Authorization;
using CustomAuthorizationDemo.DI;
using CustomAuthorizationDemo.Security.Session;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace CustomAuthorizationDemo.Controllers
{
    [AuthorizationFilter]
    [Route("api/[controller]")]
    [ApiController]
    public class TestController : ControllerBase
    {
        [Injection]
        public IClaimsSession Session { get; set; }

        [HttpGet]
        [Route("[action]")]
        public IActionResult CurrentUser() => Ok(Session?.UserName);

        [ApiAuthorize]
        [HttpPost]
        [Route("[action]")]
        public async Task<IActionResult> AsyncTest()
        {
            var token = Session.AccessToken;
            var threadId = Thread.CurrentThread.ManagedThreadId;
            int otherThreadId = threadId;
            await Task.Run(() =>
            {
                otherThreadId = Thread.CurrentThread.ManagedThreadId;
                System.Diagnostics.Debug.Assert(threadId != otherThreadId);
                System.Diagnostics.Debug.Assert(token == Session.AccessToken);
            });
            await Task.Delay(1000);
            var newThreadId = Thread.CurrentThread.ManagedThreadId;
            //调用异步方法后，会重新从线程池中恢复一个线程作为当前线程，所以不适合通过Thread.CurrentPrincipal保存用户信息。
            if (threadId != newThreadId)
            {
                //但是自行实现的ClaimsSession类会从HttpContextAccessor.HttpContext.User属性读取用户信息，不受影响
                System.Diagnostics.Debug.Assert(token == Session.AccessToken);
                return Conflict("当前线程(从线程池获取)与之前的线程不同，但获取HttpContextAccessor.HttpContext.User属性值不会变");
            }
            return Ok();
        }

        [ApiAuthorize]
        [HttpGet("{id}")]
        public IActionResult Get(int id)=> Ok(id);

        [ApiAuthorize(PermissionNames.TestAdd)]
        [HttpPost]
        [Route("[action]")]
        public IActionResult Create()=> Ok();

        [ApiAuthorize(PermissionNames.TestEdit, RequireAllPermissions = false)]
        [HttpPost]
        [Route("[action]")]
        public IActionResult Update()=> Ok();

        [ApiAuthorize(PermissionNames.TestAdd, PermissionNames.TestEdit, RequireAllPermissions = false)]
        [HttpPost]
        [Route("[action]")]
        public IActionResult Patch() => Ok();

        [ApiAuthorize(PermissionNames.TestDelete)]
        [HttpDelete("{id}")]
        public IActionResult Delete(int id) => Ok();

    }
}